<!--
props讲解
  data: array            表格数据
  columns: Array<{       表单项
    slot?: string | { body?: string, header?: string }  插槽如果是字符串，其实等价于 {body: string}内容操作名称, { header: 头部插槽，是自定义头部用 }，
    componentName: span | Tooltip | Popover | Dialog | Actions 默认值是span，如果你的文本太长，需要隐藏，鼠标引入才显示，你可能需要设置这个值
    [stirng]: any 其余属性，都继承了el-table-column的属性
  }>    
  allowSelect: boolean   允许多选
  allowAction: boolean   允许操作
  actionName: string     当allowAction为true时，el-table-column对应的label值
  actions: {             当allowAction为true时，需要配置操作行为列表
    attrs: {}    继承el-table-column的属性
    config: {
      text: string,
      hidden: Boolean   隐藏操作按钮，输入移入才显示
      options: Array<{
        label: string,      操作名
        action: ({ $index: number, row: {} }) => void 操作函数
      }>
    }       
  }

emits 讲解
  selectChange： (row: {}) => void    多选框发生改变时触发
-->
<template>
  <div class="base--table-wrap">
    <el-table
      :data="data"
      v-bind="$attrs"
      :onSelectionChange="handleSelectionChange"
    >
      <el-table-column
        v-if="allowSelect"
        type="selection"
        width="55"
      ></el-table-column>
      <template v-for="item in _columns_" :key="item.prop">
        <el-table-column v-bind="item" v-if="item.slot">
          <template #header>
            <slot :name="item.slot.header">{{
              item.label || '自定义header'
            }}</slot>
          </template>
          <template #default="scope">
            <slot
              :name="typeof item.slot === 'string' ? item.slot : item.slot.body"
              v-bind="scope.row"
              >{{ scope.row[item.prop] || '需要自定义' }}</slot
            >
          </template>
        </el-table-column>
        <el-table-column v-else v-bind="item">
          <template #default="scope">
            <component
              :is="item.componentName || 'span'"
              :content="scope.row[item.prop]"
              :title="item.label"
              >{{ scope.row[item.prop] }}</component
            >
          </template>
        </el-table-column>
      </template>
      <slot />
      <el-table-column v-if="allowAction" fixed="right" v-bind="actions.attrs">
        <template #default="scope">
          <Actions v-bind="{ ...actions.config, scope }" />
        </template>
      </el-table-column>
    </el-table>
    <div class="page-box" v-if="pageOptions && pageOptions.total">
      <pagination
        background
        layout="prev, pager, next, jumper"
        v-bind="pageOptions"
        @current-change="handleCurrentPageChange"
      ></pagination>
    </div>
    <el-checkbox v-model="isDrawer"></el-checkbox>
  </div>
  <el-drawer v-model="isDrawer" title="显示字段" :direction="'rtl'">
    <el-checkbox
      :model-value="checkAllColumns"
      :indeterminate="isIndeterminate"
      @change="handleCheckAllColumnsChange"
      >Check all</el-checkbox
    >
    <template v-for="(item, index) in _columns" :key="index">
      <el-checkbox v-model="item.visibled">{{ item.label }}</el-checkbox>
    </template>
  </el-drawer>
</template>

<script>
import {
  ElTable,
  ElTableColumn,
  ElDrawer,
  ElCheckboxGroup,
  ElCheckbox
} from 'element-plus'
import { Tooltip, Popover, Dialog, Actions } from './components'
import Pagination from '../Pagination/index.vue'
import { computed, ref } from 'vue'
export default {
  name: 'BaseTable',
  components: {
    ElTable,
    ElTableColumn,
    ElDrawer,
    Pagination,
    ElCheckboxGroup,
    ElCheckbox,
    Tooltip,
    Popover,
    Dialog,
    Actions
  },
  props: {
    allowSelect: Boolean,
    allowAction: Boolean,
    actionName: {
      type: String,
      default: '操作'
    },
    actions: {
      type: Object,
      default() {
        return {
          attrs: {},
          config: {
            text: '...',
            options: []
          }
        }
      }
    },
    data: {
      type: Array,
      default: () => []
    },
    // 表格项
    columns: {
      type: Array,
      default: () => []
    },
    pageOptions: {
      type: Object,
      default: () => ({
        pageSize: 10,
        total: 0,
        currentPage: 1
      })
    }
  },
  emits: ['selectChange', 'currentChange'],
  setup(props, { emit }) {
    const isDrawer = ref(false)

    const _columns = ref(
      props.columns.map((item) => Object.assign({}, { visibled: true }, item))
    )

    const _columns_ = computed(() =>
      _columns.value.filter((item) => item.visibled)
    )

    const checkAllColumns = computed(
      () => _columns.value.length === _columns_.value.length
    )

    const isIndeterminate = computed(
      () =>
        _columns_.value.length > 0 &&
        _columns.value.length !== _columns_.value.length
    )

    const handleCheckAllColumnsChange = () => {
      _columns.value = _columns.value.map((item) =>
        Object.assign({}, item, { visibled: checkAllColumns.value })
      )
    }

    const handleSelectionChange = (value) => {
      emit('selectChange', value)
    }
    const handleCurrentPageChange = (value) => {
      emit('currentChange', value)
    }

    return {
      isDrawer,
      _columns,
      _columns_,
      checkAllColumns,
      isIndeterminate,
      handleSelectionChange,
      handleCurrentPageChange,
      handleCheckAllColumnsChange
    }
  }
}
</script>

<style lang="scss" scoped>
.page-box {
  margin-top: 20px;
}
</style>

<style lang="scss">
.base--table-wrap {
  .feedback-btn {
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    word-break: break-all;
  }
}
</style>
